/**
 * Copyright (c) 2024 - present OpenTiny HUICharts Authors.
 * Copyright (c) 2024 - present Huawei Cloud Computing Technologies Co., Ltd.
 *
 * Use of this source code is governed by an MIT-style license.
 *
 * THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
 * BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
 * A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
 *
 */
var Interpolation = {
	Linear: function (v, k) {
			var m = v.length - 1;
			var f = m * k;
			var i = Math.floor(f);
			var fn = Interpolation.Utils.Linear;
			if (k < 0) {
					return fn(v[0], v[1], f);
			}
			if (k > 1) {
					return fn(v[m], v[m - 1], m - f);
			}
			return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
	},
	Bezier: function (v, k) {
			var b = 0;
			var n = v.length - 1;
			var pw = Math.pow;
			var bn = Interpolation.Utils.Bernstein;
			for (var i = 0; i <= n; i++) {
					b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
			}
			return b;
	},
	CatmullRom: function (v, k) {
			var m = v.length - 1;
			var f = m * k;
			var i = Math.floor(f);
			var fn = Interpolation.Utils.CatmullRom;
			if (v[0] === v[m]) {
					if (k < 0) {
							i = Math.floor((f = m * (1 + k)));
					}
					return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
			}
			else {
					if (k < 0) {
							return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
					}
					if (k > 1) {
							return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
					}
					return fn(v[i ? i - 1 : 0], v[i], v[m < i + 1 ? m : i + 1], v[m < i + 2 ? m : i + 2], f - i);
			}
	},
	Utils: {
			Linear: function (p0, p1, t) {
					return (p1 - p0) * t + p0;
			},
			Bernstein: function (n, i) {
					var fc = Interpolation.Utils.Factorial;
					return fc(n) / fc(i) / fc(n - i);
			},
			Factorial: (function () {
					var a = [1];
					return function (n) {
							var s = 1;
							if (a[n]) {
									return a[n];
							}
							for (var i = n; i > 1; i--) {
									s *= i;
							}
							a[n] = s;
							return s;
					};
			})(),
			CatmullRom: function (p0, p1, p2, p3, t) {
					var v0 = (p2 - p0) * 0.5;
					var v1 = (p3 - p1) * 0.5;
					var t2 = t * t;
					var t3 = t * t2;
					return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
			},
	},
};
export default Interpolation;